package com.accesshollywood.grfxOrdering.panels;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.tree.DefaultTreeModel;

import org.jdesktop.swingx.VerticalLayout;
import org.joda.time.DateTime;

import com.accesshollywood.SQL.GFXSQL;
import com.accesshollywood.SQL.GrfxDateTime;
import com.accesshollywood.components.EditableListWithPopup.EditableListModel;
import com.accesshollywood.components.FoldablePanel;
import com.accesshollywood.grfxOrdering.GRFXOrdersMain;
import com.accesshollywood.grfxOrdering.OrderMainGUI;
import com.accesshollywood.grfxOrdering.ViewFilterCheckBox;
import com.accesshollywood.grfxOrdering.ViewFilterTreeNode;
import com.accesshollywood.grfxOrdering.basics.DueDateFilter;
import com.accesshollywood.grfxOrdering.basics.SearchFilter;
import com.accesshollywood.grfxOrdering.basics.Users;
import com.accesshollywood.indexables.ViewFilterPreset;
import com.accesshollywood.viewFiltering.ViewFilter;
import com.accesshollywood.viewFiltering.ViewFilterGroup;
import com.accesshollywood.viewFiltering.ViewFilterTemplate;
import com.accesshollywood.viewFiltering.ViewFilters;
import com.lavantech.gui.comp.DateTimePicker;

public class ViewFiltersMasterPanel extends JPanel {
	public Component										parent;
	DefaultTreeModel										viewFilterTreeModel;
	DefaultListModel										viewPresetTreeModel;

	public LinkedHashMap<ViewFilter, ViewFilterCheckBox>	viewFilterCheckBoxHash;
	public ArrayList<ViewFilterCheckBox>					allViewFilterCheckBoxes;
	public static ArrayList<ViewFilter>						selectedFilters;

	JTextField												txtSearch;
	public String											searchColumn	= "gfxOrder";
	ViewFilterCheckBox										searchFilterCheck;
	ViewFilterCheckBox										dueDateFilterCheck;

	public DateTimePicker									dateTimePickerSTART;
	public DateTimePicker									dateTimePickerEND;
	String													dateSTART		= "";
	String													dateEND			= "";
	public JComboBox										comboBoxQuickDate;
	public JComboBox										comboBoxQuickTime;

	public boolean											doRefresh		= true;

	JButton													btn_ClearFilters;

	ViewFilterPresetPanel									viewFilterPresetPanel;
	private JPanel											foldables;

	public ViewFiltersMasterPanel(Component parent) {
		super();
		this.parent = parent;
		viewFilterCheckBoxHash = new LinkedHashMap<ViewFilter, ViewFilterCheckBox>();
		allViewFilterCheckBoxes = new ArrayList<ViewFilterCheckBox>();
		selectedFilters = new ArrayList<ViewFilter>();

		this.addHierarchyListener(new HierarchyListener() {

			@Override
			public void hierarchyChanged(HierarchyEvent arg0) {
				for (FoldablePanel currFoldable : OrderMainGUI.allFoldables) {
					if (currFoldable instanceof ViewFilterGroupPanel) {
						ViewFiltersMasterPanel.this.paintAll(ViewFiltersMasterPanel.this.getGraphics());
						currFoldable.doFoldUnfold(FoldablePanel.FOLD_SPEED.FAST);
						System.out.println("hi");

					}
				}
			}
		});
	}

	public static boolean forceRefresh() {
		boolean force = false;
		if (selectedFilters.isEmpty()) {
			return false;
		} else {
			return true;
		}
	}

	public void create() {
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

		JScrollPane scrollPane_ViewFilter = new JScrollPane();
		JScrollPane scrollPane_ViewPresets = new JScrollPane();

		JSplitPane splitViewPreset = new JSplitPane();
		splitViewPreset.setOrientation(JSplitPane.VERTICAL_SPLIT);
		splitViewPreset.setTopComponent(scrollPane_ViewFilter);
		splitViewPreset.setBottomComponent(scrollPane_ViewPresets);
		splitViewPreset.setDividerLocation(500);

		JPanel viewFilterFoldables = createViewFilterFoldables();

		btn_ClearFilters = new JButton("Clear Filters");
		viewFilterFoldables.add(btn_ClearFilters);

		scrollPane_ViewFilter.setViewportView(viewFilterFoldables);

		viewFilterPresetPanel = new ViewFilterPresetPanel();
		viewFilterPresetPanel.viewFiltersMasterPanel = this;
		// viewFilterPresetPanel.btn_SavePreset.addActionListener(new SavePresetButtonClick());
		scrollPane_ViewPresets.setViewportView(viewFilterPresetPanel);

		btn_ClearFilters.addActionListener(new ClearFiltersButtonClick());

		add(splitViewPreset);
	}

	public JPanel createViewFilterFoldables() {
		foldables = new JPanel();
		foldables.setLayout(new VerticalLayout());
		foldables.setAlignmentY(TOP_ALIGNMENT);

		createSearchFilter();
		createDueDateFilter();

		for (ViewFilterGroup currGroup : ViewFilters.viewFilterGroups) {
			ViewFilterGroupPanel newGroupPanel = new ViewFilterGroupPanel(currGroup.groupName);

			OrderMainGUI.allFoldables.add(newGroupPanel);

			newGroupPanel.setAlignmentY(BOTTOM_ALIGNMENT);
			foldables.add(newGroupPanel);

			for (ViewFilterTemplate currFilterTemplate : currGroup.filters) {
				ViewFilter newFilter = new ViewFilter(currFilterTemplate);
				ViewFilterCheckBox filterCheck = new ViewFilterCheckBox(newFilter);
				filterCheck.addActionListener(new ViewFilterCheckListener());
				filterCheck.setAlignmentY(TOP_ALIGNMENT);
				allViewFilterCheckBoxes.add(filterCheck);
				viewFilterCheckBoxHash.put(filterCheck.viewFilter, filterCheck);
				newGroupPanel.filterSubPanel.add(filterCheck);
			}

			// newGroupPanel.makeFoldable(FoldablePanel.FOLD_STATE.CLOSED);
			newGroupPanel.makeFoldable(FoldablePanel.FOLD_STATE.OPEN);
		}

		this.repaint();

		return foldables;
	}

	public void createSearchFilter() {
		ViewFilterGroupPanel newSearchPanel = new ViewFilterGroupPanel("Search");
		OrderMainGUI.allFoldables.add(newSearchPanel);

		newSearchPanel.setAlignmentY(BOTTOM_ALIGNMENT);
		foldables.add(newSearchPanel);

		searchFilterCheck = new ViewFilterCheckBox(new SearchFilter());
		searchFilterCheck.addActionListener(new ViewFilterCheckListener());
		searchFilterCheck.setAlignmentY(TOP_ALIGNMENT);

		allViewFilterCheckBoxes.add(searchFilterCheck);
		viewFilterCheckBoxHash.put(searchFilterCheck.viewFilter, searchFilterCheck);
		searchFilterCheck.setEnabled(false);
		newSearchPanel.filterSubPanel.add(searchFilterCheck);

		txtSearch = new JTextField();
		txtSearch.setMaximumSize(new Dimension(2147483647, 20));
		txtSearch.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void changedUpdate(DocumentEvent arg0) {
				setCheckEnabled();
			}

			@Override
			public void insertUpdate(DocumentEvent arg0) {
				setCheckEnabled();
			}

			@Override
			public void removeUpdate(DocumentEvent arg0) {
				setCheckEnabled();
			}

			public void setCheckEnabled() {
				if (txtSearch.getText().length() == 0) {
					searchFilterCheck.setEnabled(false);
				} else {
					searchFilterCheck.setEnabled(true);
				}
			}
		});
		newSearchPanel.filterSubPanel.add(txtSearch);
		txtSearch.setColumns(10);

		// newSearchPanel.makeFoldable(FoldablePanel.FOLD_STATE.CLOSED);
		newSearchPanel.makeFoldable(FoldablePanel.FOLD_STATE.OPEN);
	}

	public void createDueDateFilter() {
		ViewFilterGroupPanel newDueDatePanel = new ViewFilterGroupPanel("DueDate");
		OrderMainGUI.allFoldables.add(newDueDatePanel);

		newDueDatePanel.setAlignmentY(BOTTOM_ALIGNMENT);
		foldables.add(newDueDatePanel);

		dueDateFilterCheck = new ViewFilterCheckBox(new DueDateFilter());
		dueDateFilterCheck.addActionListener(new ViewFilterCheckListener());
		dueDateFilterCheck.setAlignmentY(TOP_ALIGNMENT);

		allViewFilterCheckBoxes.add(dueDateFilterCheck);
		viewFilterCheckBoxHash.put(dueDateFilterCheck.viewFilter, dueDateFilterCheck);
		newDueDatePanel.filterSubPanel.add(dueDateFilterCheck);

		dateTimePickerSTART = new DateTimePicker();
		dateTimePickerSTART.setDate(new Date());
		dateTimePickerSTART.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				changeDateRange();
				if (dueDateFilterCheck.isSelected() && doRefresh) {
					GRFXOrdersMain.refresh(true);
				}
			}
		});
		newDueDatePanel.filterSubPanel.add(dateTimePickerSTART);

		dateTimePickerEND = new DateTimePicker();
		dateTimePickerEND.setDate(new Date());
		dateTimePickerEND.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				changeDateRange();
				if (dueDateFilterCheck.isSelected() && doRefresh) {
					GRFXOrdersMain.refresh(true);
				}
			}
		});
		newDueDatePanel.filterSubPanel.add(dateTimePickerEND);

		comboBoxQuickDate = new JComboBox();
		comboBoxQuickDate.addItem("Custom Range");
		comboBoxQuickDate.addItem("Whenever");
		comboBoxQuickDate.addItem("Today");
		comboBoxQuickDate.addItem("Tomorrow");
		comboBoxQuickDate.addItem("Next Week");
		comboBoxQuickDate.addItem("Last Week");
		comboBoxQuickDate.addItem("Past");
		comboBoxQuickDate.addItem("Future");
		comboBoxQuickDate.addActionListener(new dueDatePresetAction());
		newDueDatePanel.filterSubPanel.add(comboBoxQuickDate);

		comboBoxQuickTime = new JComboBox();
		comboBoxQuickTime.addItem("All Day");
		comboBoxQuickTime.addItem("Morning");
		comboBoxQuickTime.addItem("Afternoon");
		comboBoxQuickTime.addItem("Evening");
		comboBoxQuickTime.addActionListener(new dueDatePresetAction());
		newDueDatePanel.filterSubPanel.add(comboBoxQuickTime);

		// newDueDatePanel.makeFoldable(FoldablePanel.FOLD_STATE.CLOSED);
		newDueDatePanel.makeFoldable(FoldablePanel.FOLD_STATE.OPEN);
	}

	public class dueDatePresetAction implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			String datePreset = (String) comboBoxQuickDate.getSelectedItem();

			if (datePreset.equals("Today") || datePreset.equals("Tomorrow")) {
				comboBoxQuickTime.setEnabled(true);
			} else {
				comboBoxQuickTime.setSelectedIndex(0);
				comboBoxQuickTime.setEnabled(false);
			}

			String timePreset = (String) comboBoxQuickTime.getSelectedItem();

			DateTime startDate = new DateTime(dateTimePickerSTART.getDate());
			DateTime endDate = new DateTime(dateTimePickerEND.getDate());

			if (datePreset.equals("Today")) {
				startDate = new DateTime();
				endDate = new DateTime();
			} else if (datePreset.equals("Tomorrow")) {
				startDate = new DateTime().plusDays(1);
				endDate = new DateTime().plusDays(1);
			} else if (datePreset.equals("Next Week")) {
				startDate = new DateTime();
				endDate = new DateTime().plusDays(7);
			} else if (datePreset.equals("Last Week")) {
				startDate = new DateTime().plusDays(-7);
				endDate = new DateTime();
			} else if (datePreset.equals("Past")) {
				startDate = new DateTime(0);
				endDate = new DateTime();
			} else if (datePreset.equals("Future")) {
				startDate = new DateTime();
				endDate = new DateTime(Long.MAX_VALUE / 2);
			} else if (datePreset.equals("Whenever")) {
				startDate = new DateTime(0);
				endDate = new DateTime(Long.MAX_VALUE / 2);
			}

			if (timePreset.equals("All Day")) {
				startDate = startDate.withTime(0, 0, 0, 0);
				endDate = endDate.withTime(23, 59, 59, 0);
			} else if (timePreset.equals("Morning")) {
				startDate = startDate.withTime(0, 0, 0, 0);
				endDate = endDate.withTime(12, 00, 0, 0);
			} else if (timePreset.equals("Afternoon")) {
				startDate = startDate.withTime(12, 0, 0, 0);
				endDate = endDate.withTime(4, 0, 0, 0);
			} else if (timePreset.equals("Evening")) {
				startDate = startDate.withTime(4, 0, 0, 0);
				endDate = endDate.withTime(23, 59, 59, 0);
			}

			dateTimePickerSTART.setDate(startDate.toDate());
			dateTimePickerEND.setDate(endDate.toDate());
		}
	}

	public void changeDateRange() {
		GrfxDateTime start;
		GrfxDateTime end;
		doRefresh = false;
		if (dueDateFilterCheck.isSelected()) {
			start = new GrfxDateTime(dateTimePickerSTART);
			end = new GrfxDateTime(dateTimePickerEND);
			if (start.rawDateTime.isAfter(end.rawDateTime)) {
				Date tempDate = dateTimePickerSTART.getDate();
				dateTimePickerSTART.setDate(dateTimePickerEND.getDate());
				dateTimePickerEND.setDate(tempDate);
				start = new GrfxDateTime(dateTimePickerSTART);
				end = new GrfxDateTime(dateTimePickerEND);
			} else {
				dateSTART = start.rawDateTime.getMillis() + "";
				dateEND = end.rawDateTime.getMillis() + "";
			}
		} else {
			dateSTART = "0";
			dateEND = "9999999999999";
		}
		doRefresh = true;
	}

	public void refreshBasedOnDateRange() {
		if (dueDateFilterCheck.isSelected()) {
			GRFXOrdersMain.refresh(true);
		}
	}

	public void setFromPreset(ViewFilterPreset viewFilterPreset) {
		for (int i = 0; i < allViewFilterCheckBoxes.size(); i++) {
			allViewFilterCheckBoxes.get(i).setSelected(false);
		}

		// for (int i = 0; i < viewFilterPreset.checkedFilters.size(); i++) {
		// ViewFilter currViewFilter = viewFilterPreset.checkedFilters.get(i);
		// for(ViewFilter currViewFilter : viewFilterPreset.getViewFilterList().getCheckedFilters().values()){
		Iterator itr = viewFilterPreset.getViewFilterList().iterator();
		while (itr.hasNext()) {
			ViewFilter currViewFilter = (ViewFilter) itr.next();
			ViewFilterCheckBox currCheck = viewFilterCheckBoxHash.get(currViewFilter);
			currCheck.setSelected(true);
			// currCheck.doClick();
		}

		applyFilters();
		/*
		 * for (int i = 0; i < OrderMainGUI.allFoldables.size(); i++) {
		 * if (OrderMainGUI.allFoldables.get(i) instanceof ViewFilterGroupPanel) {
		 * ((ViewFilterGroupPanel) OrderMainGUI.allFoldables.get(i)).setBackgroundIfAnyChecked();
		 * }
		 * }
		 */
	}

	public void applyFilters() {
		selectedFilters.clear();
		ViewFilterCheckBox currCheckBox;
		for (int i = 0; i < allViewFilterCheckBoxes.size(); i++) {
			// allViewFilterCheckBoxes.get(i).setSelected(false);
			currCheckBox = allViewFilterCheckBoxes.get(i);
			ViewFilterGroupPanel p = ((ViewFilterGroupPanel) currCheckBox.getParent().getParent());

			if (currCheckBox.isSelected()) {
				selectedFilters.add(currCheckBox.viewFilter);
				p.numChecked++;
			} else {
				selectedFilters.remove(currCheckBox.viewFilter);
				p.numChecked--;
			}
			p.setBackgroundIfAnyChecked();

			if (currCheckBox.viewFilter instanceof SearchFilter && currCheckBox.isSelected()) {
				// ArrayList<Integer> orderNumbers = new ArrayList<Integer>();
				String searchText = txtSearch.getText();

				searchColumn =
						"gfxOrder JOIN itemList ON gfxOrder.idItemList = itemList.idItemList ";
				searchColumn += "JOIN item ON itemList.idItem = item.idItem ";
				searchColumn += "JOIN textList ON item.idTextList = textList.idTextList ";
				searchColumn += "JOIN text ON textList.idText = text.idText ";
				searchColumn += "WHERE MATCH (text) AGAINST ('" + searchText + "')";

			} else {
				searchColumn = "gfxOrder";
			}
		}
		// ((OrderListPanel) parent).refreshOrderGUI();
		GRFXOrdersMain.refresh(true);
	}

	public DefaultTreeModel populateViewFilters() {
		String newGroupName = "";
		String currGroupName = "";

		ViewFilterTreeNode top = new ViewFilterTreeNode("View Filters");
		viewFilterTreeModel = new DefaultTreeModel(top);
		ViewFilterTreeNode newGroup = null;
		ViewFilterTreeNode newFilter = null;

		ResultSet filterGroupTreeRS;
		try {
			filterGroupTreeRS = GFXSQL.getResultSet("ViewFilterGroupTree", "*", "");
			while (filterGroupTreeRS.next()) {
				newGroupName = filterGroupTreeRS.getString("groupName");
				if (!newGroupName.equals(currGroupName)) {
					newGroup = new ViewFilterTreeNode(filterGroupTreeRS.getString("groupName"));
					top.add(newGroup);
				}
				newFilter = new ViewFilterTreeNode(filterGroupTreeRS.getString("filterName"), filterGroupTreeRS.getString("whereCondition"));
				newGroup.add(newFilter);
				currGroupName = newGroupName;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return viewFilterTreeModel;
	}

	@SuppressWarnings("unchecked")
	public String getWhereConditions() {
		String whereConditions = "";
		new ArrayList<String>();
		String prevGroupName = "";
		String currentGroupName = "";

		Collections.sort(selectedFilters, new Comparator() {
			public int compare(Object o1, Object o2) {
				ViewFilter v1 = (ViewFilter) o1;
				ViewFilter v2 = (ViewFilter) o2;
				return v1.getGroupName().compareToIgnoreCase(v2.getGroupName());
			}
		});

		searchColumn = "gfxOrder";
		GFXSQL.setArchiveAsActiveDB(false);

		if (selectedFilters.size() > 0) {
			for (int i = 0; i < selectedFilters.size(); i++) {
				ViewFilter currFilter;

				if (selectedFilters.get(i) instanceof SearchFilter) {
					currFilter = (SearchFilter) selectedFilters.get(i);

					ArrayList<Integer> orderNumbers = new ArrayList<Integer>();
					String searchText = txtSearch.getText();
					searchColumn = "gfxOrder join ";

					searchColumn += "(SELECT idOrder, text.text from text join textList USING(idText) join item USING(idTextList) join itemList USING (idItem) join gfxOrder USING (idItemList) WHERE MATCH(text.text) AGAINST ('" + searchText
							+ "') ";
					searchColumn += "UNION ";
					searchColumn += "SELECT idOrder, still.description from still join stillList USING(idStill) join item USING(idStillList) join itemList USING (idItem) join gfxOrder USING (idItemList) WHERE MATCH(still.description) AGAINST ('"
							+ searchText + "') ";
					searchColumn += "UNION ";
					searchColumn += "SELECT idOrder, footage.description from footage join footageList USING(idFootage) join item USING(idFootageList) join itemList USING (idItem) join gfxOrder USING (idItemList) WHERE MATCH(footage.description) AGAINST ('"
							+ searchText + "')) AS MATCHES ";
					searchColumn += "USING(idOrder)";

					currFilter.setWhereCondition("true");
				} else {
					currFilter = (ViewFilter) selectedFilters.get(i);

					if (currFilter.getFilterName().equals("Archived")) {
						GFXSQL.setArchiveAsActiveDB(true);
					} else {
						GFXSQL.setArchiveAsActiveDB(false);
					}
				}
				currentGroupName = currFilter.getGroupName();
				if (!currentGroupName.equals("Archive")) {
					if (currentGroupName.equals("DueDate")) {
						changeDateRange();
						whereConditions += " AND (((dueDate > " + dateSTART + ") AND (dueDate < " + dateEND + "))";
					} else {
						if (!currentGroupName.equals(prevGroupName)) {
							if (prevGroupName.equals("")) {
								whereConditions += " AND (" + currFilter.getWhereCondition();
							} else {
								whereConditions += ") AND (" + currFilter.getWhereCondition();
							}
						} else {
							whereConditions += " OR " + currFilter.getWhereCondition();
						}
					}
				}
				prevGroupName = currentGroupName;
			}
			whereConditions += ")";
			if (whereConditions.equals(")")) {
				whereConditions = "";
			}
		}
		return whereConditions;
	}

	public class ViewFilterCheckListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			ViewFilterCheckBox currCheckBox = (ViewFilterCheckBox) e.getSource();
			ViewFilterGroupPanel p = ((ViewFilterGroupPanel) currCheckBox.getParent().getParent());

			applyFilters();
		}
	}

	public class ClearFiltersButtonClick implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			selectedFilters.clear();
			for (int i = 0; i < allViewFilterCheckBoxes.size(); i++) {
				allViewFilterCheckBoxes.get(i).setSelected(false);
			}

			for (int i = 0; i < OrderMainGUI.allFoldables.size(); i++) {
				if (OrderMainGUI.allFoldables.get(i) instanceof ViewFilterGroupPanel) {
					((ViewFilterGroupPanel) OrderMainGUI.allFoldables.get(i)).setBackgroundIfAnyChecked();
				}
			}
			((OrderListPanel) parent).refreshOrderGUI(true);
		}

	}

	public class SavePresetButtonClick implements ActionListener {
		@SuppressWarnings("unchecked")
		@Override
		public void actionPerformed(ActionEvent arg0) {
			ViewFilterPreset newPreset = new ViewFilterPreset();
			newPreset.setOwner(Users.currentUser);

			newPreset.setName((String) JOptionPane.showInputDialog(parent,
					"Preset Name:\n",
					"Customized Dialog",
					JOptionPane.PLAIN_MESSAGE,
					null,
					null,
					"new preset"));

			if (newPreset.getName() != null && newPreset.getName().length() > 0) {
				Collections.sort(selectedFilters, new Comparator() {
					public int compare(Object o1, Object o2) {
						ViewFilter v1 = (ViewFilter) o1;
						ViewFilter v2 = (ViewFilter) o2;
						return v1.getGroupName().compareToIgnoreCase(v2.getGroupName());
					}
				});

				if (selectedFilters.size() > 0) {
					for (int i = 0; i < selectedFilters.size(); i++) {
						ViewFilter currFilter = (ViewFilter) selectedFilters.get(i);
						// newPreset.getCheckedFilters().put(currFilter.hashCode(), currFilter);
						newPreset.getViewFilterList().put(currFilter.hashCode(), currFilter);
					}
				}

				newPreset.toSQL();
				// ((DefaultListModel) viewFilterPresetPanel.viewPresetList.getModel()).addElement(newPreset);
				((EditableListModel) viewFilterPresetPanel.viewPresetList.getModel()).addElement(newPreset);
			}
		}
	}
}
